﻿using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using EventPlanner.Models;
using PagedList;
using EventPlanner.Authorization;
using System.Web.Security;

namespace EventPlanner.Controllers
{
    public class EventoController : Controller
    {
        private DropCreateDatabaseIfModelChanges<EventPlannerContext> c = new DropCreateDatabaseIfModelChanges<EventPlannerContext>();
        private readonly IEventPlannerContext _db;

        public EventoController(IEventPlannerContext db) { _db = db; }

        public ActionResult Buscar(FormCollection collection)
        {
            string evento = collection.Get("Nombre");

            return RedirectToAction("Index");
        }


        //
        // GET: /Evento/
        [Authorize(Roles="Publisher")]
        public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
        {
            return ListadosEventos(sortOrder, currentFilter, searchString, page, "Publisher");
        }


        public ViewResult TodosLosEventos(string sortOrder, string currentFilter, string searchString, int? page)
        {
            string h = _db.GetUsuarioActual();
            if (h != "")
                if (EventPlanner.Authorization.util.UserIsAdmin(h))
                    return ListadosEventos(sortOrder, currentFilter, searchString, page, "Administrator");
            return ListadosEventos(sortOrder, currentFilter, searchString, page, "Todos");

        }
        [Authorize(Roles = "Guest")]
        public ViewResult EventosParticipante(string sortOrder, string currentFilter, string searchString, int? page)
        {
            return ListadosEventos(sortOrder, currentFilter, searchString, page, "Participante");

        }

        private ViewResult ListadosEventos(string sortOrder, string currentFilter, string searchString, int? page, string tipo)
        {
            var usuarioActual = _db.GetUsuarioActual();
            ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
            ViewBag.OrgSortParm = sortOrder == "Org" ? "Org desc" : "Org";
            ViewBag.LugarSortParm = sortOrder == "Lugar" ? "Lugar desc" : "Lugar";
            ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";

            if (Request.HttpMethod == "GET")
            {
                searchString = currentFilter;
            }
            else
            {
                page = 1;
            }
            ViewBag.CurrentFilter = searchString;
            var eventos = from s in _db.Evento
                      
                          select s;
            if (tipo == "Publisher")
            {
                if (!String.IsNullOrEmpty(searchString))
                {
                    eventos = from s in eventos
                              where (s.Nombre.ToUpper().Contains(searchString.ToUpper())
                                           || s.Organizador.Nombre.ToUpper().Contains(searchString.ToUpper()))
                                           && s.Creador == usuarioActual
                              select s;
                }
                else
                    eventos = from s in eventos
                              where s.Creador == usuarioActual
                              select s;
            }
            if (tipo == "Administrator")
            {
                if (!String.IsNullOrEmpty(searchString))
                {
                    eventos = from s in eventos
                              where (s.Nombre.ToUpper().Contains(searchString.ToUpper())
                                           || s.Organizador.Nombre.ToUpper().Contains(searchString.ToUpper()))

                              select s;
                }
                else
                    eventos = from s in eventos
                             
                              select s;
            }

            if (tipo == "Participante")
            {
                if (!String.IsNullOrEmpty(searchString))
                {
                    eventos = from s in eventos
                              join p in _db.Participantes on s.id equals p.EventoId
                              where (s.Nombre.ToUpper().Contains(searchString.ToUpper())
                                           || s.Organizador.Nombre.ToUpper().Contains(searchString.ToUpper()))
                                           && p.Usuario == usuarioActual && s.Fecha >= DateTime.Now
                              select s;
                }
                else
                    eventos = from s in eventos
                              join p in _db.Participantes on s.id equals p.EventoId
                              where p.Usuario == usuarioActual && s.Fecha >= DateTime.Now
                              select s;
            }

            if (tipo == "Todos")
                if (!String.IsNullOrEmpty(searchString))
                {
                    eventos = from s in eventos
                              where s.Nombre.ToUpper().Contains(searchString.ToUpper())
                                           || s.Organizador.Nombre.ToUpper().Contains(searchString.ToUpper()) && s.Fecha>=DateTime.Now
                              select s;
                }
                else
                {
                    eventos = from s in eventos
                             
                              where s.Fecha>=DateTime.Now
                              select s;
                }
            ViewBag.NameAddOn = ViewBag.DateAddOn = ViewBag.OrgAddOn = ViewBag.LugarAddOn = "";
           
            switch (sortOrder)
            {
                case "Name desc":
                    eventos = eventos.OrderByDescending(s => s.Nombre);
                    ViewBag.NameAddOn = "\u2193";
                    break;
                case "Date":
                    eventos = eventos.OrderBy(s => s.Fecha);
                    ViewBag.DateAddOn = "\u2191";
                    break;
                case "Date desc":
                    eventos = eventos.OrderByDescending(s => s.Fecha);
                    ViewBag.DateAddOn = "\u2193";
                    break;
                case "Org":
                    eventos = eventos.OrderBy(s => s.Organizador.Nombre);
                    ViewBag.OrgAddOn = "\u2191";
                    break;
                case "Org desc":
                    eventos = eventos.OrderByDescending(s => s.Organizador.Nombre);
                    ViewBag.OrgAddOn = "\u2193";
                    break;
                case "Lugar":
                    eventos = eventos.OrderBy(s => s.Lugar);
                    ViewBag.LugarAddOn = "\u2191";
                    break;
                case "Lugar desc":
                    eventos = eventos.OrderByDescending(s => s.Lugar);
                    ViewBag.LugarAddOn = "\u2193";
                    break;
                default:
                    eventos = eventos.OrderBy(s => s.Nombre);
                    ViewBag.NameAddOn = "\u2191";
                    break;
            }
            int pageSize = 10;
            int pageNumber = (page ?? 1);
            switch (tipo)
            {
                case "Publisher":
                    return View(eventos.ToPagedList(pageNumber, pageSize));
                case "Participante":
                    return View("Participante/Index", eventos.ToPagedList(pageNumber, pageSize));
                case "Administrator":
                    return View("Administrator/Index", eventos.ToPagedList(pageNumber, pageSize));
                default:
                    return View("Visitor/Index", eventos.ToPagedList(pageNumber, pageSize));
            }
        }
      
        //
        // GET: /Evento/Details/5
        [Authorize(Roles = "Publisher")]
        [AutorizarCreador]
        public ActionResult Details(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            return View(evento);
           
        }

        public ActionResult DetailsTodos(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            return View("Visitor/Details",evento);

        }

        //
        // GET: /Evento/Create
        [Authorize(Roles = "Publisher")]
        public ActionResult Create()
        {
            SelectList orgs = getOrganizadores(_db.GetUsuarioActual());
            if(orgs.Count() == 0)
                return RedirectToAction("CustomError", "Error", new { MensajeError = EventPlanner.Resources.Shared.CustomError.lbl_NoExistenOrg });
            ViewBag.names = orgs;
            return View();
        }

        private SelectList getOrganizadores()
        {
            var usuarioActual = _db.GetUsuarioActual();
            var organizadores = from c in _db.Organizador
                                where c.Creador == usuarioActual && c.Activa == true
                                select new { OrganizadorId = c.id, OrganizadorNombre = c.Nombre };

            SelectList sl = new SelectList(organizadores, "OrganizadorId", "OrganizadorNombre");
            return sl;
        }

        private SelectList getOrganizadores(string creador)
        {
            var organizadores = from c in _db.Organizador
                                where c.Creador == creador && c.Activa == true
                                select new { OrganizadorId = c.id, OrganizadorNombre = c.Nombre };

            SelectList sl = new SelectList(organizadores, "OrganizadorId", "OrganizadorNombre");
            return sl;
        }



        //
        // POST: /Evento/Create
        [Authorize(Roles = "Publisher")]
        [HttpPost]
        public ActionResult Create(Evento evento)
        {
            if (ModelState.IsValid)
            {
                evento.Creador = _db.GetUsuarioActual();
                evento.Fecha = evento.Fecha.AddHours(evento.Hora.Hour).AddMinutes(evento.Hora.Minute);
                _db.Evento.Add(evento);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.names = getOrganizadores();
            return View(evento);
        }

        //
        // GET: /Evento/Edit/5
        [Authorize(Roles = "Publisher,Administrator")]
        [AutorizarCreador]
        public ActionResult Edit(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            ViewBag.names = getOrganizadores(evento.Creador); //Existe al menos un organizador, si o si
            
            return View(evento);
        }

        //
        // POST: /Evento/Edit/5

        [Authorize(Roles = "Publisher,Administrator")]
        [HttpPost]
        public ActionResult Edit(Evento evento)
        {
            if (ModelState.IsValid)
            {
                
                _db.SetModified(evento);
                evento.Fecha.Subtract(new TimeSpan(evento.Fecha.Hour, evento.Fecha.Minute, 0));
                evento.Fecha = evento.Fecha.AddHours(evento.Hora.Hour).AddMinutes(evento.Hora.Minute);
                _db.SaveChanges();
                if (EventPlanner.Authorization.util.UserIsAdmin(_db.GetUsuarioActual())) return RedirectToAction("TodosLosEventos");
                return RedirectToAction("Index");
            }
            ViewBag.names = getOrganizadores(evento.Creador);

           
            return View(evento);
            
        }

        //
        // GET: /Evento/Delete/5

        [Authorize(Roles = "Publisher,Administrator")]
        [AutorizarCreador]
        public ActionResult Delete(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            return View(evento);
        }

        //
        // POST: /Evento/Delete/5

        [HttpPost, ActionName("Delete")]
        [Authorize(Roles = "Publisher,Administrator")]
        public ActionResult DeleteConfirmed(int id)
        {
            Evento evento = _db.Evento.Find(id);
            _db.Evento.Remove(evento);
            _db.SaveChanges();
            if (EventPlanner.Authorization.util.UserIsAdmin(_db.GetUsuarioActual())) return RedirectToAction("TodosLosEventos");
            return RedirectToAction("Index");
        }

        [Authorize(Roles = "Guest")]
        public ActionResult RegistrarUsuarioParticipante(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            //El cupo está completo o el usuario ya se registró en ese evento o es un evento pasado
            if (evento.CupoCompleto() || evento.GetParticipantePorUsuario(_db.GetUsuarioActual()).IsValid() || evento.Fecha < DateTime.Today)
                return RedirectToAction("DetailsTodos", new { id = id });
            Participante participante = new Participante();
            participante.Correo = _db.GetMembershipInfo("email");
            participante.EventoId = id;
            participante.Nombre = _db.GetUsuarioActual();
            participante.Usuario = _db.GetUsuarioActual();
            participante.Confirmado = false;

            _db.Participantes.Add(participante);
            _db.SetModified(evento);
            
            evento.Participantes.Add(participante);
            _db.SaveChanges();
            return RedirectToAction("DetailsTodos", new { id = id });
        }
        [Authorize(Roles = "Guest")]
        public ActionResult BorrarUsuarioParticipante(int id)
        {
            Evento evento = _db.GetEvento(id);
            if (!evento.IsValid())
                return RedirectToAction("CustomError", "Error", new { MensajeError = "No existe el evento" });
            Participante participante = new Participante();
            participante.Correo = Membership.GetUser().Email;
            participante.EventoId = id;
            participante.Nombre = _db.GetUsuarioActual();
            participante.Usuario = _db.GetUsuarioActual();
            participante.Confirmado = false;

            _db.Participantes.Add(participante);
            _db.SetModified(evento);
            
            evento.Participantes.Add(participante);
            _db.SaveChanges();
            return RedirectToAction("DetailsTodos", new { id = id });
        }    
        protected override void Dispose(bool disposing)
        {
            ((EventPlannerContext)_db).Dispose();
            base.Dispose(disposing);
        }
    }

}